#pragma once

#include "Log.hpp"
#include "Err.hpp"
#include "Socket.hpp"
#include "Protocol.hpp"

class TcpClient
{
public:
    TcpClient(std::string serverIp, uint16_t serverPort)
        : serverIp_(serverIp), serverPort_(serverPort)
    {
    }
    void Init()
    {
        sock_.createSocket();
    }
    void Start()
    {
        int i = 5;
        while (i > 0)
        {
            if (sock_.Connect(serverIp_, serverPort_) != -1)
                break;
            LOG(WARNING, "connect sserver fail! %d", i--);
            sleep(1);
        }
        if (i == 0)
        {
            LOG(FATAL, "connect server fail");
            exit(CONNECT_ERR);
        }
        ServiceIO();
    }
    void ServiceIO()
    {
        while (true)
        {
            std::string str;
            std::cout << "Please Enter:#";
            std::getline(std::cin, str);
            // 1.判断是否需要退出
            if (str == "quit")
            {
                break;
            }
            // 2.分割输入的字符串
            yui::Request req;
            std::string ops = "+-*/%";
            int pos = 0;
            for (auto e : ops)
            {
                pos = str.find(e);
                if (pos != std::string::npos)
                {
                    break;
                }
            }
            req.x_ = Util::StrToInt(str.substr(0,pos));
            req.y_ = Util::StrToInt(str.substr(pos+1));
            req.op_ = str[pos];

            //3.序列化
            std::string sendMsg;
            req.Serialization(&sendMsg);
            //4.添加报头
            yui::AddHeader(sendMsg);
            //5.发送数据
            send(sock_.getSock(),sendMsg.c_str(),sendMsg.size(),0);
            //6.获取数据
            std::string inBuff;
            std::string package;
            int len = 0;
            while(true)
            {
                len = yui::ReadPackage(sock_.getSock(),inBuff,&package);
                if(len<0)
                {
                    exit(READ_ERR);
                }
                else if(len>0)
                {
                    break;
                }
            }
            //7.移除报头
            yui::RemoveHeader(package,len);
            //8.反序列化
            yui::Reaponse resp;
            if(resp.Deserialization(package) == false)
            {
                LOG(WARNING,"Deserialization fail");
                continue;
            }
            //9.获取结果
            std::cout<<"the result: "<<resp.result_<<" "<<resp.code_<<std::endl;
        }
    }
    ~TcpClient()
    {
        sock_.Close();
    }

private:
    yui::Socket sock_;
    std::string serverIp_;
    uint16_t serverPort_;
};